#ifndef __ST1_H__
#define __ST1_H__

#include <systemc.h>
#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
#include "datastruct.hh"
#include <queue> 


using namespace std;
using namespace sc_core;

struct notifynext{
    sc_event trigger;
    uint32_t info0;
    uint32_t info1;
    uint32_t info2;
};

struct ST1 : public sc_module { // define a systemC module

    tlm_utils::simple_target_socket<ST1> st1_tsocket;
    tlm_utils::simple_initiator_socket<ST1> st12st3_isocket;

    sc_fifo<l2pnode> cmdset;
    l2pnode l1[4];
    int l1_loc=0;
    l2pnode l2[4][4];
    int l2_all=0, l2_remain=0;
    l2pnode l3[4][16];
    int l3_all=0, l3_remain=0;
    l2pnode l4[4][64];
    int l4_all=0, l4_remain=0;
    l2pnode l5[4][256];
    int l5_all=0, l5_remain=0;
    l2pnode dsa[8192];
    int dsa_index=0;
    notifynext l1t2, l2t3, l3t4, l4t5, l5tdsa;
    
    SC_CTOR(ST1):cmdset(4) {// constructor function, to be explained later
        SC_THREAD(st1_thread); // register a member function to the kernel
        SC_THREAD(l1_thread);
        SC_THREAD(l2_thread);
        SC_THREAD(l3_thread);
        SC_THREAD(l4_thread);
        SC_THREAD(l5_thread);
        SC_THREAD(dsa_thread);
        st1_tsocket.register_b_transport(this, &ST1::st1_b_transport);
    }
    void st1_thread(void);
    void l1_thread(void);
    void l2_thread(void);
    void l3_thread(void);
    void l4_thread(void);
    void l5_thread(void);
    void dsa_thread(void);
    void st1_b_transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay);
};

#endif //__ST1_H__